from datetime import datetime
from operator import and_
from flask import g
from wtforms import Form
from sqlalchemy import Column, DateTime
from . import AutoCommit, db
from sqlalchemy.orm import Session
from flask_sqlalchemy import SQLAlchemy, Model
from sqlalchemy.orm import Query


class BaseModel(db.Model):
    """ 主要职能：
        1. 提供模型属性拷贝方法
        2. 提供数据库相关操作对象
        3. 事务上下文环境，即自动提交到数据库
        4. 
    """
    __abstract__ = True  # 解释为抽象类
    create_time = Column(DateTime, default=datetime.now)
    delete_time = Column(DateTime, default=None)
    update_time = Column(DateTime,
                         onupdate=datetime.now)

    db: SQLAlchemy = db
    session: Session = db.session

    def set_attr(self, form_or_dict: Form, filter_keys=[]) -> Model:
        """ 给模型赋值 """
        data = None
        if isinstance(form_or_dict, dict):
            data = form_or_dict
        elif isinstance(form_or_dict, Form):
            data = form_or_dict.data
        else:
            data = form_or_dict.__dict__
        for k, v in data.items():
            if k not in filter_keys and hasattr(self, k):
                setattr(self, k, v)
        return self

    @staticmethod
    def auto_commit() -> AutoCommit:
        """ 创建事务管理区域，用with使用 """
        return AutoCommit(db=db)

    @classmethod
    def current_user_filter(cls, where=None) -> Query:
        """ 附加：当前用户的数据条件 """
        if where is not None:
            return cls.query.filter(and_(cls.user_id == g.current_user.id, where))
        else:
            return cls.query.filter(cls.user_id == g.current_user.id)
